
// 获取画布
var canvasEle = document.getElementById('MyCanvas')
// 获取音频元素
var audioEle = document.getElementById('MyAudio')
audioEle.volume = 0.2

// 绘图函数，专门把图形绘制到 canvas 上
// 用一个数组来获取音频数据
function draw2Canvas(array) {
  var canvasCtx = canvasEle.getContext('2d')
  // 元素长宽
  var w = canvasEle.width
  var h = canvasEle.height

  // 每次绘制前先清空 canvas
  canvasCtx.clearRect(0, 0, w, h)

  // 数组长度
  var alt = array.length

  // 计算柱形条宽度
  var barW = w / alt
  var barH
  // 每个柱形条起始 x 坐标
  var x = 0

  // for 循环一根一根绘制
  for (let i = 0; i < array.length; i++) {
    const num = array[i];

    // 柱形条高度，用常熟保证其有打底高度
    barH = num + 10
    // 渲染出来的柱形条高度可能会很高，需要降低
    var renderH = barH / 8
    // 颜色
    canvasCtx.fillStyle = '#bce5ef'
    // 绘制柱形条
    // y 的高度可以使得其居中
    canvasCtx.fillRect(x, (h - renderH) / 2, barW, renderH)
    // 设置下一个柱形条 x 轴位置，这里根据实际需要进行调整，增加常数是为了能让其间隔开来
    x += barW + 3.6
  }
}

// 创建音频上下文
function initAudioCtx() {
  // 获取上下文对象
  var audioCtx = new window.AudioContext()
  // 将音频元素作为音频源
  var audioSrc = audioCtx.createMediaElementSource(audioEle)
  // 构建分析器，用于获取音频频域数组数据
  var analyser = audioCtx.createAnalyser()


  // 设置频域范围，越长则获取的越多，默认 2048
  analyser.fftSize = 256
  // 获取到的数组长度
  var alt = analyser.frequencyBinCount

  // 连接到音频输出地
  audioSrc.connect(analyser)
  analyser.connect(audioCtx.destination)

  // 设置定时器，获取数据并绘图
  setInterval(() => {
    var array = new Uint8Array(alt)
    analyser.getByteFrequencyData(array)
    draw2Canvas(array)
  }, 30);
}

var init = false

// 需要等音频资源正常加载后才能正常初始化上下文
// 监听播放事件，并初始化音频上下文
audioEle.addEventListener('play', () => {
  var newSrc = document.getElementById('MyInput').value
  if (audioEle.src != newSrc) {
    audioEle.src = newSrc
  }
  if (!init) {
    initAudioCtx()
    init = true
  }
})

// 页面第一次加载渲染一下 canvas
// 数组长度为设置 fftSize 的一半 
draw2Canvas(new Uint8Array(128))